#include "mcMain.h"
#include <time.h>
#include <iostream>
#include "../strategy/MoveGen.h"

using namespace std;

double mcMain::TIME_PER_CHOICE = 9.5;
int mcMain::TREE_DEPTH = 3;


mcMain::mcMain()//const RegionBoard * regionBoard, double startTime)
{
	//	this->endTime=startTime+CLOCKS_PER_SEC*this->TIME_PER_CHOICE;
	//	this->root= new mcNode(NULL,regionBoard);
}

Move mcMain::nextMove(const RegionBoard& rb) {
	clock_t currenttime;
	start = clock();
	finish = start + this->TIME_PER_CHOICE * CLOCKS_PER_SEC;
	mcNode rnode(NULL, NULL);
	this->root = &rnode;
	this->root->Color = rb.getBoard().toPlay();

	root->possible_next_moves.Include(root);
	currenttime = clock();

	mcNode* curNode;

	/*
	 curNode = *(root->possible_next_moves.PopFront());
	 if(root->moveList[0]!=NULL)
	 cout<<"movelist is not null";
	 return root->moveList[0];
	 */
	SgDebug() << "entering while\n";

	while (true) {
		if (root->possible_next_moves.IsEmpty())
			break;

		curNode = root->possible_next_moves.PopFront();
		curNode->print();

		if (curNode->depth > 1) {
			if (curNode->depth < TREE_DEPTH) {
				Board tempb;
				tempb.copy(rb.getBoard());
				RegionBoard currb(tempb);
				currb.copy(rb);
				MoveList ml = curNode->getMoveList();
				genBoard(ml, tempb, currb);

				MoveGen* mg = new MoveGen(currb);
				mg->findMoves();

				//do not have this function. need to be implement.
				//must have 5 of movelist
				//return the move list in MoveGen
				MoveList m = mg->getMoveList();

				for (int i = 0; i < 5; ++i) {
					if (m[i] != NULL)
						curNode->extends_this(&m[i]);
				}
			} else {
				SgDebug() << "SSSSSSSSimulate : node " << curNode->mcNode_num
						<< "\n";
				curNode->simulate(rb);

			}
		} else {
			Board tempb;
			tempb.copy(rb.getBoard());
			RegionBoard currb(tempb);
			currb.copy(rb);

			MoveGen* mg = new MoveGen(currb);
			mg->findMoves();
			MoveList m = mg->getMoveList();
			for (int i = 0; i < 5; ++i) {
				if (m[i] != NULL)
					curNode->extends_this(&m[i]);
				SgDebug() << "extends this   :" << curNode->mcNode_num << "\n";
			}
		}

		currenttime = clock();

	}//endwhile


	int wins = 0;
	Move finalMove;
	Move tmove;
	mcNode* tnode;

	int tempi = 0;
	while (tempi < 5) {

		tnode = root->sons_of_this_node[tempi];
		tmove = root->moveList[tempi];

		if (tnode->total_win_game > wins) {
			wins = tnode->total_win_game;
			finalMove = tmove;
			SgDebug() << "FINAL MOVE FINAL MOVE";
		}

		++tempi;
	}
	return finalMove;

}

void mcMain::setTime(double input) {
	this->TIME_PER_CHOICE = input;
}

void mcMain::genBoard(MoveList list, Board& board, RegionBoard& rb) {
	for (int i = 0; i < list.Length(); i++) {
		board.play(list[i]);
		rb.onExecMove(list[i]);
	}
}
